
#ifndef __CRYPT_O_CHAIN_H
#define __CRYPT_O_CHAIN_H

#include <vector>

#include "../aprtools/APRBucketBrigade.h"
#include "../iface/debug.h"

#include "CryptoPipeBlock.h"

#include "EncryptionKey.h"
#include "DecryptionKey.h"
#include "SigningKey.h"
#include "CheckingKey.h"

/** A wrapper for the creation, storage and processing of cryptography
 * workflows, in the form of a set of data pipes. */
class CryptOChain
{
   public:
      CryptOChain(apr_pool_t *imp);
      CryptOChain(APRBucketBrigade &iinput, APRBucketBrigade &ioutput, apr_pool_t *mp);
      ~CryptOChain();
      void addEncryptionPipe(EncryptionKey *enc);
      void addDecryptionPipe(DecryptionKey *dec);
      void addSigningPipe(SigningKey *sgn);
      void addCheckingPipe(CheckingKey *chk);
      void addCompressionPipe();
      void addDecompressionPipe();
      void buildEncryptionChain(EncryptionKey *crypto, SigningKey *signing, int docompress);
      void buildDecryptionChain(DecryptionKey *crypto, CheckingKey *signing, int dodecompress);
      // Process data block and return processed data
      char *processDataBlock(const char *inputblock, apr_size_t inputsize, apr_size_t *outputsize);
      // Begin processing of the data pipe
      int processPipeBegin();
      // Step through the data, recording data movement
      int processPipeStep(int64_t inputblocksize, int64_t outputblocksize);
      // End processing of the data pipe
      int processPipeEnd();
      // Check security of process
      int processWasSecure() { return trusted; }
   private:
      /** This class is uncopyable. */
      CryptOChain(const CryptOChain &o);
      /** This class is uncopyable. */
      CryptOChain &operator=(const CryptOChain &o);
      /** Pointer to the input bucket brigade. */
      APRBucketBrigade *input;
      /** Pointer to the output bucket brigade. */
      APRBucketBrigade *output;
      /** A vector of bucket brigades between each component. */
      std::vector<APRBucketBrigade *> brigades;
      /** A vector of pipe segments. */
      std::vector<CryptoPipeBlock *> cryptopipes;
      /** A flag to be set when a signature is checked successfully and found
       * to be matching, therefore meaning that the data processed is to be
       * trusted, as it has asserted its identity. */
      int trusted;
      /** Memory pool to use locally. */
      apr_pool_t *mp;
};

#endif
